﻿namespace AddressBook.Business.Contact
{
	#region "Using Statements"
	using System;
	using System.Collections.Generic;
	using System.Linq;
	using System.Text;

	using Csla;
	using Csla.Data;
	using Csla.Validation;

	using AddressBook.Business.Person;
	#endregion

	[Serializable]
	public class ContactEmailAddress : BusinessBase<ContactEmailAddress>
	{
		#region "Business Methods"

		#region "Private Static Variables"

		private static PropertyInfo<Int32> EmaillAddressIdProperty = RegisterProperty<Int32>(p => p.EmailAddressId);
		private static PropertyInfo<Int32> ContactIdProperty = RegisterProperty<Int32>(p => p.ContactId);
		private static PropertyInfo<String> EmailAddressProperty = RegisterProperty<String>(p => p.EmailAddress);
		private static PropertyInfo<Int32> EmailAddressTypeIdProperty = RegisterProperty<Int32>(p => p.EmailAddressTypeId);
		private static PropertyInfo<SmartDate> ModifiedDateProperty = RegisterProperty<SmartDate>(a => a.ModifiedDate);

		#endregion

		#region "Public Properties"

		public Int32 EmailAddressId
		{
			get { return GetProperty(EmaillAddressIdProperty); }
			internal set { LoadProperty(EmaillAddressIdProperty, value); }
		}

		public Int32 ContactId
		{
			get { return GetProperty(ContactIdProperty); }
			internal set { LoadProperty(ContactIdProperty, value); }
		}

		public String EmailAddress
		{
			get { return GetProperty(EmailAddressProperty); }
			set { SetProperty(EmailAddressProperty, value); }
		}

		public Int32 EmailAddressTypeId
		{
			get { return GetProperty(EmailAddressTypeIdProperty); }
			set { SetProperty(EmailAddressTypeIdProperty, value); }
		}

		public String ModifiedDate
		{
			get { return GetProperty(ModifiedDateProperty).ToString(); }
		}

		#endregion

		#endregion

		#region "Business Rules"

		protected override void AddBusinessRules()
		{
			ValidationRules.AddRule(CommonRules.StringRequired, new RuleArgs(EmailAddressProperty));
			ValidationRules.AddRule(CommonRules.StringMaxLength, new CommonRules.MaxLengthRuleArgs(EmailAddressProperty, 50));

			ValidationRules.AddRule(CommonRules.IntegerMinValue, new CommonRules.IntegerMinValueRuleArgs(EmailAddressTypeIdProperty, 1));
		}

		#endregion

		#region "Factory Methods"

		internal static ContactEmailAddress NewEmailAddress(Int32 emailAddressTypeId)
		{
			return DataPortal.CreateChild<ContactEmailAddress>(emailAddressTypeId);
		}

		internal static ContactEmailAddress NewEmailAddress(String emailAddress, Int32 emailAddressTypeId)
		{
			return DataPortal.CreateChild<ContactEmailAddress>(emailAddress, emailAddressTypeId);
		}

		internal static ContactEmailAddress GetEmailAddress(AddressBook.Business.Model.ContactEmailAddress data)
		{
			return DataPortal.FetchChild<ContactEmailAddress>(data);
		}

		private ContactEmailAddress()
		{ /* require use of factory methods */ }

		#endregion

		#region "Data Access"

		protected override void Child_Create()
		{

		}

		private void Child_Create(Int32 emailAddressTypeId)
		{
			using (BypassPropertyChecks)
			{
				this.EmailAddressId = 0;
				this.EmailAddress = String.Empty;
				this.EmailAddressTypeId = emailAddressTypeId;
			}
		}

		private void Child_Create(String emaillAddress, Int32 emailAddressTypeId)
		{
			using (BypassPropertyChecks)
			{
				this.EmailAddressId = 0;
				this.EmailAddress = emaillAddress;
				this.EmailAddressTypeId = emailAddressTypeId;
			}
		}

		private void Child_Fetch(AddressBook.Business.Model.ContactEmailAddress data)
		{
			using (BypassPropertyChecks)
			{
				this.EmailAddressId = data.EmailAddressId;
				this.ContactId = data.ContactId;
				this.EmailAddress = data.EmailAddress.EmailAddress1;
				this.EmailAddressTypeId = data.EmailAddressTypeId;

				LoadProperty(ModifiedDateProperty, data.ModifiedDate);
			}
		}

		private void Child_Insert(Contact contact)
		{
			using (var ctx = ContextManager<AddressBook.Business.Model.AddressBookDataContext>.GetManager(AddressBook.Business.Model.Database.AddressBook))
			{
				// insert contact address data
				using (BypassPropertyChecks)
				{
					AddressBook.Business.Model.ContactEmailAddress emailAddress = new AddressBook.Business.Model.ContactEmailAddress();

					this.EmailAddressId = Person.EmailAddress.AddEmailAddress(this.EmailAddress);

					emailAddress.EmailAddressId = this.EmailAddressId;
					emailAddress.ContactId = contact.Id;
					emailAddress.EmailAddressTypeId = this.EmailAddressTypeId;
					emailAddress.ModifiedDate = System.DateTime.Now;

					ctx.DataContext.ContactEmailAddresses.InsertOnSubmit(emailAddress);
					ctx.DataContext.SubmitChanges();
				}
			}
		}

		private void Child_Update()
		{
			using (var ctx = ContextManager<AddressBook.Business.Model.AddressBookDataContext>.GetManager(AddressBook.Business.Model.Database.AddressBook))
			{
				// update contact address data
				using (BypassPropertyChecks)
				{
					AddressBook.Business.Model.ContactEmailAddress emailAddress = ctx.DataContext.ContactEmailAddresses.First(ce => ce.EmailAddressId == this.EmailAddressId && ce.ContactId == this.ContactId);

					Person.EmailAddress.UpdateEmailAddress(this.EmailAddressId, this.EmailAddress);

					emailAddress.EmailAddressId = this.EmailAddressId;
					emailAddress.ContactId = this.ContactId;
					emailAddress.EmailAddressTypeId = this.EmailAddressTypeId;
					emailAddress.ModifiedDate = System.DateTime.Now;

					ctx.DataContext.SubmitChanges();
				}
			}
		}

		private void Child_DeleteSelf(Contact contact)
		{
			using (var ctx = ContextManager<AddressBook.Business.Model.AddressBookDataContext>.GetManager(AddressBook.Business.Model.Database.AddressBook))
			{
				int emailAddressId = this.EmailAddressId;
				AddressBook.Business.Model.ContactEmailAddress emailAddress = ctx.DataContext.ContactEmailAddresses.First(ce => ce.EmailAddressId == this.EmailAddressId && ce.ContactId == this.ContactId);

				ctx.DataContext.ContactEmailAddresses.DeleteOnSubmit(emailAddress);
				ctx.DataContext.SubmitChanges();

				Person.EmailAddress.RemoveEmailAddress(emailAddressId);
			}
		}

		#endregion
	}
}
